﻿using isky.webapi.requests;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace isky.webapi.DataAccess
{
    public class RFMwebapi
    {
        private readonly string orgUrl = string.Empty;
        private readonly string adfsUrl = string.Empty;
        private readonly string authUrl = string.Empty;
        private readonly string userName = string.Empty;
        private readonly string passWord = string.Empty;
        private readonly string webApiUrl = string.Empty;
        public RFMwebapi()
        {
            orgUrl = AppSettingConfig.orgUrl;
            adfsUrl = AppSettingConfig.adfsUrl;
            authUrl = AppSettingConfig.authUrl;
            userName = AppSettingConfig.userName;
            passWord = AppSettingConfig.passWord;
            webApiUrl = AppSettingConfig.webApiUrl;
        }
        /// <summary>
        /// 批量创建客户分类
        /// </summary>
        /// <param name="dyrfm"></param>
        /// <param name="callerID"></param>
        /// <returns></returns>
        public CRMBatchResult CreateBatchRFMaccountmodel(dynamic dyrfm, Guid callerID = default(Guid))
        {
            try
            {
                XrmHttpClient xrmHttpClient = new XrmHttpClient(userName, passWord, orgUrl, adfsUrl, authUrl);
                var handler = xrmHttpClient.GetWebRequestHandler();
                var xrmWebApi = new CRMWebAPI(webApiUrl, new HttpClient(handler));
                return xrmWebApi.Create("new_rfmaccountmodels", dyrfm, new HttpClient(handler)).Result;
            }
            catch (CRMWebAPIException ex)
            {
                throw ex.InnerException;
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        /// <summary>
        /// 批量事务操作
        /// </summary>
        /// <param name="cRMEntities"></param>
        /// <param name="callerid"></param>
        public CRMBatchResult BatchOperator(CRMEntityDynamic[] cRMEntities, Guid callerid = default(Guid))
        {
            var cRMEntitieList = cRMEntities.ToList();

            Action<MultipartContent, string> patchOrPostAction = (multContent, apiUrl) =>
            {
                int contentID = 1;
                var changesetID = "changeset_" + Guid.NewGuid().ToString();
                MultipartContent changeSetContent = new MultipartContent("mixed", changesetID);
                List<HttpMessageContent> httpMsgContentList = new List<HttpMessageContent>(cRMEntities.Length);

                cRMEntitieList.ForEach(cRMEntitie =>
                {
                    var fullUrl = string.Concat(apiUrl, cRMEntitie.entityCollectionName);
                    if (cRMEntitie.httpMethod == "PATCH")
                    {
                        if (cRMEntitie.entityDynamics != null)
                        {
                            foreach (var entityDynamic in cRMEntitie.entityDynamics)
                            {
                                var dataIndexer = entityDynamic as IDictionary<string, Object>;
                                if (dataIndexer != null)
                                {
                                    var patchUrl = string.Concat(fullUrl, $"({dataIndexer[cRMEntitie.primaryKeyName].ToString()})");
                                    HttpRequestMessage req = new HttpRequestMessage(new HttpMethod("PATCH"), patchUrl);
                                    req.Content = new StringContent(JsonConvert.SerializeObject(entityDynamic), Encoding.UTF8, "application/json");
                                    HttpMessageContent content = new HttpMessageContent(req);
                                    content.Headers.Remove("Content-Type");
                                    content.Headers.TryAddWithoutValidation("Content-Type", "application/http");
                                    content.Headers.TryAddWithoutValidation("Content-Transfer-Encoding", "binary");
                                    content.Headers.TryAddWithoutValidation("Content-ID", contentID.ToString());
                                    content.Headers.TryAddWithoutValidation("If-Match", "*");
                                    contentID++;
                                    httpMsgContentList.Add(content);
                                }
                            }
                        }
                    }
                    else if (cRMEntitie.httpMethod == "POST")
                    {
                        if (cRMEntitie.entityDynamics != null)
                        {
                            foreach (var entityDynamic in cRMEntitie.entityDynamics)
                            {
                                HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, fullUrl);
                                req.Content = new StringContent(JsonConvert.SerializeObject(entityDynamic), Encoding.UTF8, "application/json");
                                HttpMessageContent content = new HttpMessageContent(req);
                                content.Headers.Remove("Content-Type");
                                content.Headers.TryAddWithoutValidation("Content-Type", "application/http");
                                content.Headers.TryAddWithoutValidation("Content-Transfer-Encoding", "binary");
                                content.Headers.TryAddWithoutValidation("Content-ID", contentID.ToString());
                                contentID++;
                                httpMsgContentList.Add(content);
                            }
                        }
                    }
                });

                if (httpMsgContentList.Count() > 0)
                {
                    httpMsgContentList.ForEach(msgContent => changeSetContent.Add(msgContent));
                    multContent.Add(changeSetContent);
                }
                else
                {
                    throw new ArgumentException("MultipartContent is Null");
                }
            };

            XrmHttpClient xrmHttpClient = new XrmHttpClient(userName, passWord, orgUrl, adfsUrl, authUrl);
            var handler = xrmHttpClient.GetWebRequestHandler();
            var xrmWebApi = new CRMWebAPI(webApiUrl, new HttpClient(handler));
            var entityCollectionNames = cRMEntities.Select(r => r.entityCollectionName).ToArray();

            try
            {
                return xrmWebApi.BatchOperation(patchOrPostAction, new HttpClient(handler), entityCollectionNames).Result;
            }
            catch (AggregateException webex)
            {
                throw webex?.InnerException;
            }
            catch (Exception ex)
            {
                throw ex?.InnerException;
            }
        }



        /// <summary>
        /// 创建会员信息
        /// </summary>
        /// <param name="accountdy"></param>
        /// <returns></returns>
        public Guid CreateRFMaccountmodel(dynamic dyrfm)
        {
            XrmHttpClient xrmHttpClient = new XrmHttpClient(userName, passWord, orgUrl, adfsUrl, authUrl);
            var handler = xrmHttpClient.GetWebRequestHandler();
            var xrmWebApi = new CRMWebAPI(webApiUrl, new HttpClient(handler));
            try
            {
                return xrmWebApi.Create("new_rfmaccountmodels", dyrfm).Result;
            }
            catch (AggregateException ex)
            {
                throw ex.InnerException;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }


        public CRMUpdateResult UpdateAccountInfo(dynamic dyaccount, Guid accountid)
        {
            XrmHttpClient xrmHttpClient = new XrmHttpClient(userName, passWord, orgUrl, adfsUrl, authUrl);
            var handler = xrmHttpClient.GetWebRequestHandler();
            var xrmWebApi = new CRMWebAPI(webApiUrl, new HttpClient(handler));
            try
            {
                return xrmWebApi.Update("accounts", accountid, dyaccount, false).Result;
            }
            catch (AggregateException ex)
            {
                throw ex?.InnerException;
            }
            catch (Exception ex)
            {
                throw ex?.InnerException;
            }
        }
    }
}
